#!/bin/bash
#------------------------------------------------------------------------------
# =========                 |
# \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
#  \\    /   O peration     | Website:  https://openfoam.org
#   \\  /    A nd           | Copyright (C) 2016-2018 OpenFOAM Foundation
#    \\/     M anipulation  |
#------------------------------------------------------------------------------
# License
#     This file is part of OpenFOAM.
#
#     OpenFOAM is free software: you can redistribute it and/or modify it
#     under the terms of the GNU General Public License as published by
#     the Free Software Foundation, either version 3 of the License, or
#     (at your option) any later version.
#
#     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
#     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
#     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
#     for more details.
#
#     You should have received a copy of the GNU General Public License
#     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
#
# Script
#     wmakeCollect
#
# Usage
#     wmakeCollect [OPTION] <command>
#
# Description
#     wmake scheduler for efficient parallel compilations.
#
#-------------------------------------------------------------------------------
Script=${0##*/}

usage() {
    cat<<USAGE

Usage: $Script [OPTION] <command>

options:
  -clean            Clean-up before compilation (removes old makefiles)
  -kill             Clean-up after termination (removes makefiles)
  -help  | -h       Print the usage

Collecting scheduler for fast parallel compilation of large numbers of object
files.  Can be used in compiling OpenFOAM by setting the WM_SCHEDULER variable.

When called with a compilation command it is written into a file in the
directory $WM_COLLECT_DIR.

When called without a command the files in the $WM_COLLECT_DIR directory are
combined into a single Makefile which is passed to make to compile all of the
object files efficiently in parallel.

Typical usage for compiling OpenFOAM:

  - Ensure all lnInclude directories are up-to-date:
    wmakeLnIncludeAll

  - Compile all with this scheduler:
    wmake -queue or wmake -q

USAGE
}

error() {
    exec 1>&2
    while [ "$#" -ge 1 ]; do echo "$1"; shift; done
    usage
    exit 1
}

# Set true to clean-up file if interrupted
cleanup=

while [ "$#" -gt 0 ]
do
    case "$1" in
    -h | -help)
        usage && exit 0
        ;;
    -kill | -clean)
        cleanup="true"
        shift
        ;;
    -*)
        error "unknown option: '$*'"
        break
        ;;
    *)
        break
        ;;
    esac
done


if [ -z "$WM_COLLECT_DIR" ]
then
    echo "$Script error: WM_COLLECT_DIR not set"
    exit 1
fi


if [ -n "$WM_QUIET" ]
then
    E="@"
fi


# Collected makefile for this build
makefile="$WM_COLLECT_DIR.Makefile"


# Clean-up files and exit
if [ -n "$cleanup" ]
then
    rm -rf $WM_COLLECT_DIR
    rm -f $makefile
    exit 0
fi


if [ "$#" -gt 0 ]
then
    # Make sure directories exist
    mkdir -p $WM_COLLECT_DIR

    # The current source file
    source="${@: -3:1}"

    # The current target
    object="${@: -1:1}"

    # Create a unique name for the makefile from the object path
    file=$(mktemp $WM_COLLECT_DIR/XXXXXX)

    # Add the current target to the list of objects
    echo "OBJECTS += $object" >> $file

    # Add the build rule for the current target
    echo "$object: $makefile" >> $file
    [ -z "$E" ] ||
        echo -e "\t@echo \"    compiling: ${source##*/}\"" >> $file
    echo -e "\t$E cd $PWD && \\" >> $file
    echo -e "\t${@:1:($#-1)} $object" >> $file
    echo >> $file
else
    if [ -d $WM_COLLECT_DIR ]
    then
        # Collect all the makefiles into a single makefiles for this build
        (cd $WM_COLLECT_DIR && ls -1rt | xargs cat > $makefile)

        # Add a build rule for all of the targets
        echo 'all: $(OBJECTS)' >> $makefile

        # Clear out all of the target makefiles
        rm -rf $WM_COLLECT_DIR

        # Run make on the collected makefile
        make -j $WM_NCOMPPROCS -f $makefile all

        rm -f $makefile
    fi
fi


#------------------------------------------------------------------------------
# Cleanup local variables and functions
#------------------------------------------------------------------------------

unset Script usage error


#------------------------------------------------------------------------------
